#include "CalcOverlap.h"


CalcOverlap::CalcOverlap(Parser* p)
{
	parser=p;
	group1Desired=0.0;
	group2Desired=0.0;
	group3Desired=0.0;
}


CalcOverlap::~CalcOverlap(void)
{
}

void CalcOverlap::calculate(){
	vector<ExtentEntry*>* extents;
	vector<ExtentEntry*>::iterator extentsIter;
	map<string, ExtentEntry*> group1Current;
	map<string, ExtentEntry*> group2Current;
	map<string, ExtentEntry*> group3Current;
	map<string, ExtentEntry*> group1Past;
	map<string, ExtentEntry*> group2Past;
	map<string, ExtentEntry*> group3Past;
	map<string, ExtentEntry*>::iterator mapIter;
	double group1Hit=0, group1Miss=0, group2Hit=0, group2Miss=0, group3Hit=0, group3Miss=0;
	string name;
	ExtentEntry* ex;

	bool first=true;
	bool once1=true, once2=true, once3=true;
	while ((extents = parser->ParseNextTimeSlice()) != 0){
		int time = extents->front()->getMy_time();
		group1Hit=0, group1Miss=0, group2Hit=0, group2Miss=0, group3Hit=0, group3Miss=0;
		
		for (extentsIter=extents->begin(); extentsIter!=extents->end(); extentsIter++){
			ex = (*extentsIter);
			name = calcKey(ex);

			if (once1 || once2 || once3){
				if (ex->getMy_extent()->getLun()->getPriorityGroup()==1){
					group1Desired=ex->getMy_extent()->getLun()->getDRT();
					once1=false;
				}
				else if (ex->getMy_extent()->getLun()->getPriorityGroup()==2){
					group2Desired=ex->getMy_extent()->getLun()->getDRT();
					once1=false;
				}
				else if (ex->getMy_extent()->getLun()->getPriorityGroup()==3){
					group3Desired=ex->getMy_extent()->getLun()->getDRT();
					once1=false;
				}
			}

			//compare to previous time slice
			if (!first){
				if (ex->getMy_extent()->getLun()->getPriorityGroup()==1){
					mapIter = group1Past.find(name);
					if (mapIter!=group1Past.end())
						group1Hit+=ex->getMy_stat()->getStat(rand_rm);
					else
						group1Miss+=ex->getMy_stat()->getStat(rand_rm);
				}
				else if (ex->getMy_extent()->getLun()->getPriorityGroup()==2){
					mapIter = group2Past.find(name);
					if (mapIter!=group2Past.end())
						group2Hit+=ex->getMy_stat()->getStat(rand_rm);
					else
						group2Miss+=ex->getMy_stat()->getStat(rand_rm);
				}
				else if (ex->getMy_extent()->getLun()->getPriorityGroup()==3){
					mapIter = group3Past.find(name);
					if (mapIter!=group3Past.end())
						group3Hit+=ex->getMy_stat()->getStat(rand_rm);
					else
						group3Miss+=ex->getMy_stat()->getStat(rand_rm);
				}
			}

			if (ex->getMy_extent()->getLun()->getPriorityGroup()==1)
				group1Current.insert(pair<string, ExtentEntry*> (name, ex));
			else if (ex->getMy_extent()->getLun()->getPriorityGroup()==2)
				group2Current.insert(pair<string, ExtentEntry*> (name, ex));
			else if (ex->getMy_extent()->getLun()->getPriorityGroup()==3)
				group3Current.insert(pair<string, ExtentEntry*> (name, ex));
		}

		if (!first){
			group1Overlaps.insert(pair<int, double> (time, (group1Hit/(group1Hit+group1Miss))));
			group2Overlaps.insert(pair<int, double> (time, (group2Hit/(group2Hit+group2Miss))));
			group3Overlaps.insert(pair<int, double> (time, (group3Hit/(group3Hit+group3Miss))));
		}
		first=false;

		group1Past.clear();
		group2Past.clear();
		group3Past.clear();
		group1Past = group1Current;
		group2Past = group2Current;
		group3Past = group3Current;
		group1Current.clear();
		group2Current.clear();
		group3Current.clear();
		delete extents;
	}
}

string CalcOverlap::calcKey(ExtentEntry* ex){
	char buffer[30];
	string key = "";
	_itoa_s(ex->getMy_extent()->getLun()->getM_uid(),buffer,30, 10);
	key.append(buffer);
	key.append("_");
	sprintf(buffer, "%I64d",ex->getMy_extent()->my_offset);
	key.append(buffer);
	return key;
}